package com.github.data_manage.job

import cn.hutool.core.io.FastStringWriter
import com.github.data_manage.common.DAY_FORMATTER
import com.github.data_manage.dao.FundDao
import com.github.data_manage.dao.FundMeetingDao
import com.github.data_manage.dao.FundMeetingHistoryDao
import com.github.data_manage.util.DateTimeUtils.Companion.atEndOfDay
import com.github.data_manage.util.DateTimeUtils.Companion.atStartOfDay
import freemarker.template.Template
import jakarta.annotation.PostConstruct
import org.slf4j.LoggerFactory
import org.springframework.core.env.Environment
import org.springframework.mail.javamail.JavaMailSender
import org.springframework.mail.javamail.MimeMessageHelper
import org.springframework.scheduling.TaskScheduler
import org.springframework.scheduling.support.CronTrigger
import org.springframework.stereotype.Component
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer
import java.time.LocalDate
import java.time.LocalDateTime
import kotlin.jvm.optionals.getOrNull

/**
 *
 * @author chenhainan
 * @since 2025/9/29
 */
@Component
class MeetingStatisticsJob(
    private val fundMeetingDao: FundMeetingDao,
    private val fundMeetingHistoryDao: FundMeetingHistoryDao,
    private val taskScheduler: TaskScheduler,
    private val fundDao: FundDao,
    private val freeMarkerConfigurer: FreeMarkerConfigurer,
    private val mailSender: JavaMailSender,
    private val environment: Environment
) {

    companion object {
        private val logger = LoggerFactory.getLogger(MeetingStatisticsJob::class.java)
    }


    @PostConstruct
    fun statisticsFundMeetings() {
        // 日报 每天 0 点 5 分运行
        taskScheduler.schedule({
            val now = LocalDateTime.now()
            val startTime = now.minusDays(1).atStartOfDay()
            val endTime = now.minusDays(1).atEndOfDay()
            statisticsFundMeetings(startTime, endTime, "日报")
        }, CronTrigger("0 5 0 * * ?"))
        // 周报 每周一 0 点 5 分运行
        taskScheduler.schedule({
            val now = LocalDateTime.now()
            val startTime = now.minusWeeks(1).atStartOfDay()
            val endTime = now.minusDays(1).atEndOfDay()
            statisticsFundMeetings(startTime, endTime, "周报")
        }, CronTrigger("0 5 0 ? * MON"))
        // 月报 每月一号 0 点 5 分运行
        taskScheduler.schedule({
            val now = LocalDateTime.now()
            val startTime = now.minusMonths(1).atStartOfDay()
            val endTime = now.minusDays(1).atEndOfDay()
            statisticsFundMeetings(startTime, endTime, "月报")
        }, CronTrigger("0 5 0 1 * ?"))
    }

    fun statisticsFundMeetings(start: LocalDateTime, end: LocalDateTime, statisticsType: String) {
        val fundMeetingHistories = fundMeetingHistoryDao.findAllByCreateTimeBetween(start, end)
        if (fundMeetingHistories.isEmpty()) return
        val meetingInfoMap = HashMap<String, Any>(fundMeetingHistories.size)
        meetingInfoMap["statisticsType"] = statisticsType
        meetingInfoMap["meetingCount"] = fundMeetingHistories.size
        meetingInfoMap["date"] = DAY_FORMATTER.format(LocalDate.now())
        val meetings = fundMeetingHistories.map { fundMeetingHistory ->
            val fund = fundDao.findById(fundMeetingHistory.fundId).getOrNull() ?: return@map null
            mapOf(
                Pair("fundName", fund.fundName),
                Pair("meetingTime", DAY_FORMATTER.format(fundMeetingHistory.createTime)),
                Pair("insertBy", fundMeetingHistory.insertBy ?: ""),
                Pair("otter", fundMeetingHistory.otter ?: ""),
                Pair("fundUrl", "http://www.spark-i.com:81/fund/${fund.fundId!!}"),
            )
        }.filterNotNull()
        meetingInfoMap["meetings"] = meetings

        val template: Template = freeMarkerConfigurer.configuration.getTemplate("fund_meeting_statistics.ftl")
        val statisticsInfo = FastStringWriter().use {
            template.process(meetingInfoMap, it)
            return@use it.toString()
        }
        val startTimeFormatter = DAY_FORMATTER.format(start)
        val endTimeFormatter = DAY_FORMATTER.format(end)
        logger.info("start {} end {} statisticsInfo {}", startTimeFormatter, endTimeFormatter, statisticsInfo)
        val message = mailSender.createMimeMessage()
        val helper = MimeMessageHelper(message, true, "UTF-8")
        helper.setSubject("基金会议${statisticsType}(${startTimeFormatter}-${endTimeFormatter})")
        helper.setText(statisticsInfo, true)
        helper.setTo(environment.getProperty("system.target-email-address", "1806632927@qq.com"))
        helper.setFrom(environment.getProperty("system.from-email-address", "funddatamanage@gmail.com"))
        mailSender.send(message)
    }

}